﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SharingCenter.Web.Classes.Learning
{
    using SharingCenter.Web.Classes;
    using SharingCenter.Web.Classes.enums;
    using System.Xml.Linq;
    using System.Xml.Serialization;
    using ClassLibrary;
    using SharingCenter.Web.Classes.Requests;
    using System.Xml;
    using System.IO;
    public static class LearningOperations
    {
        public static List<Sc_LearningProfile> GetUserLearningProfile(Guid userId)
        {
            
                var q = from t in scDataContext.Instance.Sc_LearningProfiles
                        where t.UserId == userId && t.Enabled
                        orderby t.CreateDate descending
                        select t;
                return q.ToList();
            
        }

        public static void DeleteProfile(Guid lpId)
        {
            Sc_LearningProfile tmp = GetProfileByProfileId(lpId);
            scDataContext.Instance.Sc_LearningProfiles.DeleteOnSubmit(tmp);
            scDataContext.Instance.SubmitChanges();
        }

        public static bool SignOffLearning(Guid signOffUserId, Guid lhId)
        {
            return Convert.ToBoolean(scDataContext.Instance.SignOffLearning(signOffUserId, lhId));
        }

        public static Sc_LearningHistory GetHistoryByHistoryId(Guid historyId, Guid? userId)
        {
            try
            {
                if (userId != null)
                {
                    using (scDataContext con = new scDataContext())
                    {
                        try
                        {
                            var q = from t in con.Sc_LearningHistories
                                    where (t.RequestorUserId == userId || t.RequesteeUserId == userId) && t.LearningHistoryId == historyId
                                    orderby t.LearningHistoryId descending
                                    select t;
                            return q.First();
                        }
                        catch { return null; }
                    }
                }
                else
                {
                    using (scDataContext con = new scDataContext())
                    {
                        try
                        {
                            var q = from t in con.Sc_LearningHistories
                                    where t.LearningHistoryId == historyId
                                    orderby t.LearningHistoryId descending
                                    select t;
                            return q.First();
                        }
                        catch { return null; }
                    }
                }
            }
            catch { return null; }
        }

        public static Sc_LearningProfile GetProfileByProfileId(Guid learningProfileId)
        {
            Sc_LearningProfile ret = null;

            try
            {
                ret = scDataContext.Instance.Sc_LearningProfiles.Single(d => d.LearningProfileId == learningProfileId);
            }
            catch { }
            return ret;
        }

        public static List<Sc_LearningProfile> GetMatchedLearningProfiles(Sc_LearningProfile learningProfileToMatch)
        {
            List<Sc_LearningProfile> ret = new List<Sc_LearningProfile>();

            var q =
                    from o in scDataContext.Instance.Sc_LearningIOs
                    join i in scDataContext.Instance.Sc_LearningIOs
                    on o.Skill equals i.Skill
                    where i.Direction == LearningSkillDirection.Input
                    && o.Direction == LearningSkillDirection.Output
                    && (
                    from s in learningProfileToMatch.Sc_LearningIOs
                    where s.Direction == LearningSkillDirection.Input
                    select s.Skill
                    ).Contains(o.Skill)
                    select o;
            var p = from s in q
                    join t in scDataContext.Instance.Sc_LearningProfiles
                    on s.LearningProfileId equals t.LearningProfileId
                    where t.UserId != learningProfileToMatch.UserId
                    select t;
                      
            ret = p.Distinct().ToList();
            return ret;
        }

        public static Guid CreateLearningHistoryOnApproval(Sc_SharedRequest request, bool submitChanges)
        {
           
            StringHelper s = new StringHelper(request.Context.ToString());
            XmlReaderSettings set = new XmlReaderSettings();
            set.ConformanceLevel = ConformanceLevel.Fragment;
            set.IgnoreComments = true;
            set.IgnoreWhitespace = true;
            XmlReader r = XmlReader.Create(s.AsMemoryStream, set);
            XmlRootAttribute root = new XmlRootAttribute("LearningRequestContext");
            root.Namespace = "";
            XmlSerializer ser = new XmlSerializer(typeof(LearningRequestContext), root);
            LearningRequestContext cxt = (LearningRequestContext)ser.Deserialize(r);
            
            Sc_LearningHistory his = new Sc_LearningHistory();
            his.RequestId = request.RequestId;
            his.RequestorUserId = request.RequestorUserId;
            his.RequesteeUserId = cxt.RequesteeUserId;
            his.RequesteeProfile = SerializeXml(GetProfileByProfileId(cxt.RequesteeProfileId));
            his.RequestorProfile = SerializeXml(GetProfileByProfileId(cxt.RequestorProfileId));
            his.LearningHistoryId = Guid.NewGuid();
            his.CreateDate = DateTime.Now;
            scDataContext.Instance.Sc_LearningHistories.InsertOnSubmit(his);
            if (submitChanges)
            {
                scDataContext.Instance.SubmitChanges();
            }
            return his.LearningHistoryId;
        }

        public static List<Sc_LearningHistory> GetLearningHistoryByUserId(Guid userId)
        {
            using (scDataContext con = new scDataContext())
            {
                var q = from t in con.Sc_LearningHistories
                        where t.RequestorUserId == userId || t.RequesteeUserId == userId
                        orderby t.LearningHistoryId descending
                        select t;
                return q.ToList();
            }
        }

        public static Sc_LearningProfile Deserialize(XElement xml)
        {
            Sc_LearningProfile p = new Sc_LearningProfile();
            p.Comment = xml.Element("Comment").Value;
            try
            {
                p.StartDate = Convert.ToDateTime(xml.Element("StartDate").Value);
                p.EndDate = Convert.ToDateTime(xml.Element("EndDate").Value);
            }
            catch { }

            p.DaysInWeek = xml.Element("DaysInWeek").Value;
            p.CreateDate = Convert.ToDateTime(xml.Element("CreateDate").Value);
            foreach (XElement item in xml.Element("Sc_LearningIOs").Elements())
            {
                Sc_LearningIO ioitem = new Sc_LearningIO();
                ioitem.Direction = (LearningSkillDirection)Enum.Parse(typeof(LearningSkillDirection), item.Element("Direction").Value);
                ioitem.Skill = item.Element("Skill").Value;
                ioitem.Level = int.Parse(item.Element("Level").Value);
                p.Sc_LearningIOs.Add(ioitem);
            }
            foreach (XElement item in xml.Element("Sc_LearningTimeSpans").Elements())
            {
                Sc_LearningTimeSpan ts = new Sc_LearningTimeSpan();
                ts.Comment = item.Element("Comment").Value;
                ts.StartTime = Convert.ToDateTime(item.Element("StartTime").Value);
                ts.EndTime = Convert.ToDateTime(item.Element("EndTime").Value);
                p.Sc_LearningTimeSpans.Add(ts);
            }
            return p;
        }

        public static XElement SerializeXml(Sc_LearningProfile p)
        {
            XElement root = new XElement("LearningProfile");
            //root.Add(new XElement("LearningProfileId", p.LearningProfileId));
            root.Add(new XElement("StartDate", p.StartDate));
            root.Add(new XElement("EndDate", p.EndDate));
            root.Add(new XElement("DaysInWeek", p.DaysInWeek));
            root.Add(new XElement("CreateDate", p.CreateDate));
            root.Add(new XElement("Comment", p.Comment));
            XElement io = new XElement("Sc_LearningIOs");
            foreach (Sc_LearningIO item in p.Sc_LearningIOs)
            {
                XElement ioitem = new XElement("Sc_LearningIO");
                ioitem.Add(new XElement("Direction", item.Direction));
                ioitem.Add(new XElement("Level", item.Level));
                ioitem.Add(new XElement("Skill", item.Skill));
                io.Add(ioitem);
            }
            root.Add(io);

            XElement ts = new XElement("Sc_LearningTimeSpans");
            foreach(Sc_LearningTimeSpan item in p.Sc_LearningTimeSpans)
            {
                XElement tsitem = new XElement("Sc_LearningTimeSpan");
                tsitem.Add(new XElement("StartTime", item.StartTime));
                tsitem.Add(new XElement("EndTime", item.EndTime));
                tsitem.Add(new XElement("Comment", item.Comment));
                ts.Add(tsitem);
            }
            root.Add(ts);

            return root;
        }
    }

}
